package de.tu_darmstadt.gdi1.towerdefense.model.monstermodel;

import java.util.Observable;
import java.util.Vector;

import de.tu_darmstadt.gdi1.towerdefense.model.TowerDefenseModel;
import de.tu_darmstadt.gdi1.towerdefense.model.mapmodel.AMap;

public class MonsterSpawner extends Observable {

	private final int monsterHealth = 20;
	private final int healthBonus = 20;
	private final int monsterMoney = 100;
	private final int moneyBonus = 150;
	private int numberOfMonstersPerWave;
	private int numberOfWavesLeft;
	private int numberOfMonstersLeftThisWave;
	private int ticksUntilNextMonsterSpawn;
	private int ticksLeft;
	private int numberOfWaves;
	private AMap tmpMap;
	private boolean gameIsWon;
	private TowerDefenseModel model;
	private Monster monster;
	private int tmp;

	
	/**
	 * constructor
	 * 
	 * @param numberOfMonsters
	 *            the number of monsters every wave
	 * @param waves
	 *            the number of waves to be spawned
	 * @param _Map
	 *            the map object of the model
	 * @param m
	 *            the towerdefensemodel
	 */
	public MonsterSpawner(int numberOfMonsters, int waves, AMap _Map,
			TowerDefenseModel m) {
		model = m;
		numberOfMonstersPerWave = numberOfMonsters;
		numberOfWavesLeft = waves;
		numberOfWaves = waves;
		numberOfMonstersLeftThisWave = numberOfMonstersPerWave;
		ticksUntilNextMonsterSpawn = 2;
		ticksLeft = ticksUntilNextMonsterSpawn;
		tmpMap = _Map;
		gameIsWon = false;
		tmp = 1;
	}

	/*
	 * spawn the next monster
	 */
	public void spawn(Vector<Monster> monsters) {
		if (numberOfMonstersLeftThisWave > 0 && ticksLeft == 0) {
			
			switch (tmp) {
			case 1:
				monster = new MonsterBlack();
				break;
			case 2:
				monster = new MonsterBlue();

				break;
			case 3:
				monster = new MonsterMult();

				break;
			case 4:
				monster = new MonsterRed();

				break;
			default:
				monster = new MonsterBlack();
				break;

			}
			
			
			monster.setLivePoints((int) (monsterHealth + 2 * healthBonus
					* (numberOfWaves - numberOfWavesLeft)));
			monster.setMoney(monsterMoney + moneyBonus
					* (numberOfWaves - numberOfWavesLeft));
			monster.setPoint(tmpMap.getWaypoint().get(0).getxCoord(), tmpMap
					.getWaypoint().get(0).getyCoord());
			tmpMap.setMonsterPosition(tmpMap.getWaypoint().get(0).getxCoord(),
					tmpMap.getWaypoint().get(0).getyCoord());
			monsters.add(monster);
			numberOfMonstersLeftThisWave--;
			ticksLeft = ticksUntilNextMonsterSpawn;
			return;
		} else {
			ticksLeft--;
			if (numberOfWavesLeft > 0 && model.getNumberOfMonsters() == 0
					&& numberOfMonstersLeftThisWave == 0) {
				numberOfWavesLeft--;
				numberOfMonstersLeftThisWave = numberOfMonstersPerWave;
				ticksLeft = 5;
				if (tmp <= 4)
					tmp++;
				else
					tmp = 1;
				setChanged();
				notifyObservers();
			}

			if (numberOfWavesLeft == 0 && model.getNumberOfMonsters() == 0) {
				gameIsWon = true;
			}

		}
	}

	public boolean isGameWon() {
		return gameIsWon;
	}

	public int getNumberOfWavesLeft() {
		return numberOfWavesLeft;
	}

}